using System;
using Rapier.Kodachi.Shared;
using iTunesLib;
using System.Drawing;
using System.IO;
using System.Threading;
using System.Runtime.InteropServices;
using System.Collections;

namespace Rapier.Kodachi.iTunes.Actions
{
    public class iTunesActionBase : Action
    {
        #region Private Members
        private Hashtable artWork = new Hashtable();
        #endregion

        #region Protected Members
        protected Bitmap playImage = (Bitmap)Rapier.Kodachi.iTunes.Properties.Resources.Play;
        protected Bitmap nextImage = (Bitmap)Rapier.Kodachi.iTunes.Properties.Resources.Next;
        protected Bitmap pauseImage = (Bitmap)Rapier.Kodachi.iTunes.Properties.Resources.Pause;
        protected Bitmap playPauseImage = (Bitmap)Rapier.Kodachi.iTunes.Properties.Resources.PlayPause;
        protected Bitmap previousImage = (Bitmap)Rapier.Kodachi.iTunes.Properties.Resources.Previous;
        protected Bitmap stopImage = (Bitmap)Rapier.Kodachi.iTunes.Properties.Resources.Stop;
        protected Bitmap trackInfoImage = (Bitmap)Rapier.Kodachi.iTunes.Properties.Resources.TrackInfo;
        protected Bitmap volumeMuteImage = (Bitmap)Rapier.Kodachi.iTunes.Properties.Resources.VolumeMute;
        #endregion

        #region Properties
        public iTunesApp itunes
        {
            get
            {
                return (this.Plugin as iTunesPlugin).iTunes;
            }
            set
            {
                (this.Plugin as iTunesPlugin).iTunes = value;
            }
        }
        #endregion

        #region Constructor
        public iTunesActionBase(Plugin plugin, string actionType, string name, string description)
            : base(plugin, actionType, name, description)
        {
            artWork.Clear();
        }
        #endregion

        #region Override Action Members
        public override bool IsValidDirect(Item directItem)
        {
            return directItem.Properties.ContainsKey("iTunes") && (bool)(directItem.Properties["iTunes"]) == true;
        }

        public override void Execute(Item[] directItems, Item[] indirectItems)
        {
        }
        #endregion

        #region Public Methods

        public bool ThumbnailCallback()
        {
            return true;
        }

        public bool IsItunesRunning()
        {
            if (itunes == null)
            {
                itunes = new iTunesAppClass();
                //other initialization stuff to the itunes guy

                itunes.OnPlayerPlayEvent += new _IiTunesEvents_OnPlayerPlayEventEventHandler(
                    delegate
                    {
                        Plugin.Host.Context.Post(new SendOrPostCallback(itunes_OnPlayerPlayEvent), null);
                    });

                itunes.OnAboutToPromptUserToQuitEvent += new _IiTunesEvents_OnAboutToPromptUserToQuitEventEventHandler(
                    delegate
                    {
                        Plugin.Host.Context.Post(new SendOrPostCallback(itunes_OnAboutToPromptUserToQuitEvent), null);
                    });
            }

            return (itunes != null);
        }

        

        public void DisplayCurrentTrackInfo(IITTrack currentTrack)
        {
            if (currentTrack != null)
            {
                NotificationPackage package = new NotificationPackage();

                package.Message = CreateMessageFromTrack(currentTrack);

                if (currentTrack.Artwork.Count > 0)
                {
                    try
                    {
                        if (artWork.Contains(currentTrack.Album))
                        {
                            package.Image = (Bitmap)artWork[currentTrack.Album];
                        }
                        else
                        {
                            string appDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
                            string filePath = Path.Combine(appDataFolder, "currentArt.bmp");
                            currentTrack.Artwork[1].SaveArtworkToFile(filePath);
                            artWork[currentTrack.Album] = new Bitmap(new Bitmap(filePath),new Size(48,48));
                             //= (Bitmap)art.GetThumbnailImage(48, 48, new Image.GetThumbnailImageAbort(ThumbnailCallback), IntPtr.Zero);
                            package.Image = (Bitmap)artWork[currentTrack.Album];
                        }               
                    }
                    catch
                    {
                    }
                }
                package.Caption = currentTrack.Artist;
                Plugin.Host.Notify(package);
            }
            else
            {
                NotificationPackage package = new NotificationPackage();
                package.Message = "Current Track Information Not Available";
                package.Caption = "No track Info";
                Plugin.Host.Notify(package);
            }
        }
        #endregion

        #region Private Methods
        private string CreateMessageFromTrack(IITTrack currentTrack)
        {
            string message = string.Empty;
            message = "Track: " + currentTrack.Name + " (" + currentTrack.Time + ")\nAlbum: " + currentTrack.Album;

            if (currentTrack.Year > 0)
            {
                message = message + " (" + currentTrack.Year.ToString() + ")";
            }

            
            message = message + "\nBitRate: " + currentTrack.BitRate.ToString() + " kbps";

            if (currentTrack.Rating > 0)
            {
                message = message + "\nRating: ";
                for (int i = 0; i < currentTrack.Rating; i+=20)
                {
                    message = message + "*";
                }
            }
            else
            {
                message = message + "\n(not rated)";
            }
             
            return message;
        }

        private string currentTime(int timeInSec)
        {
            int min = timeInSec / 60;
            int sec = timeInSec % 60;

            return string.Format("{0:0}:{1:00}", min, sec);
        }
        #endregion

        #region Event Handlers
        void itunes_OnAboutToPromptUserToQuitEvent(object o)
        {
            Marshal.ReleaseComObject(itunes);
            itunes = null;
            GC.Collect();
        }

        void itunes_OnPlayerPlayEvent(object iTrack)
        {
            if (itunes.CurrentTrack != null)
                DisplayCurrentTrackInfo(itunes.CurrentTrack);
        }


        #endregion
    }
}
